/**
 * @fileOverview The "filebrowser" plugin that adds support for file uploads and
 *               browsing.
 *
 * When a file is uploaded or selected inside the file browser, its URL is
 * inserted automatically into a field defined in the <code>filebrowser</code>
 * attribute. In order to specify a field that should be updated, pass the tab ID and
 * the element ID, separated with a colon.<br /><br />
 *
 * <strong>Example 1: (Browse)</strong>
 *
 * <pre>
 * {
 *    type : 'button',
 *    id : 'browse',
 *    filebrowser : 'tabId:elementId',
 *    label : editor.lang.common.browseServer
 * }
 * </pre>
 *
 * If you set the <code>filebrowser</code> attribute for an element other than
 * the <code>fileButton</code>, the <code>Browse</code> action will be triggered.<br /><br />
 *
 * <strong>Example 2: (Quick Upload)</strong>
 *
 * <pre>
 * {
 *    type : 'fileButton',
 *    id : 'uploadButton',
 *    filebrowser : 'tabId:elementId',
 *    label : editor.lang.common.uploadSubmit,
 *    'for' : [ 'upload', 'upload' ]
 * }
 * </pre>
 *
 * If you set the <code>filebrowser</code> attribute for a <code>fileButton</code>
 * element, the <code>QuickUpload</code> action will be executed.<br /><br />
 *
 * The filebrowser plugin also supports more advanced configuration performed through
 * a JavaScript object.
 *
 * The following settings are supported:
 *
 * <ul>
 * <li><code>action</code> &ndash; <code>Browse</code> or <code>QuickUpload</code>.</li>
 * <li><code>target</code> &ndash; the field to update in the <code><em>tabId:elementId</em></code> format.</li>
 * <li><code>params</code> &ndash; additional arguments to be passed to the server connector (optional).</li>
 * <li><code>onSelect</code> &ndash; a function to execute when the file is selected/uploaded (optional).</li>
 * <li><code>url</code> &ndash; the URL to be called (optional).</li>
 * </ul>
 *
 * <strong>Example 3: (Quick Upload)</strong>
 *
 * <pre>
 * {
 *    type : 'fileButton',
 *    label : editor.lang.common.uploadSubmit,
 *    id : 'buttonId',
 *    filebrowser :
 *    {
 *       action : 'QuickUpload', // required
 *       target : 'tab1:elementId', // required
 *       params : // optional
 *       {
 *          type : 'Files',
 *          currentFolder : '/folder/'
 *       },
 *       onSelect : function( fileUrl, errorMessage ) // optional
 *       {
 *          // Do not call the built-in selectFuntion.
 *          // return false;
 *       }
 *    },
 *    'for' : [ 'tab1', 'myFile' ]
 * }
 * </pre>
 *
 * Suppose you have a file element with an ID of <code>myFile</code>, a text
 * field with an ID of <code>elementId</code> and a <code>fileButton</code>.
 * If the <code>filebowser.url</code> attribute is not specified explicitly,
 * the form action will be set to <code>filebrowser[<em>DialogWindowName</em>]UploadUrl</code>
 * or, if not specified, to <code>filebrowserUploadUrl</code>. Additional parameters
 * from the <code>params</code> object will be added to the query string. It is
 * possible to create your own <code>uploadHandler</code> and cancel the built-in
 * <code>updateTargetElement</code> command.<br /><br />
 *
 * <strong>Example 4: (Browse)</strong>
 *
 * <pre>
 * {
 *    type : 'button',
 *    id : 'buttonId',
 *    label : editor.lang.common.browseServer,
 *    filebrowser :
 *    {
 *       action : 'Browse',
 *       url : '/ckfinder/ckfinder.html&amp;type=Images',
 *       target : 'tab1:elementId'
 *    }
 * }
 * </pre>
 *
 * In this example, when the button is pressed, the file browser will be opened in a
 * popup window. If you do not specify the <code>filebrowser.url</code> attribute,
 * <code>filebrowser[<em>DialogName</em>]BrowseUrl</code> or
 * <code>filebrowserBrowseUrl</code> will be used. After selecting a file in the file
 * browser, an element with an ID of <code>elementId</code> will be updated. Just
 * like in the third example, a custom <code>onSelect</code> function may be defined.
 */

(function() {
   // Adds (additional) arguments to given url.
   //
   // @param {String}
   //            url The url.
   // @param {Object}
   //            params Additional parameters.
   function addQueryString( url, params ) {
      var queryString = [];

      if ( !params )
         return url;
      else {
         for ( var i in params )
            queryString.push( i + "=" + encodeURIComponent( params[ i ] ) );
      }

      return url + ( ( url.indexOf( "?" ) != -1 ) ? "&" : "?" ) + queryString.join( "&" );
   }

   // Make a string's first character uppercase.
   //
   // @param {String}
   //            str String.
   function ucFirst( str ) {
      str += '';
      var f = str.charAt( 0 ).toUpperCase();
      return f + str.substr( 1 );
   }

   // The onlick function assigned to the 'Browse Server' button. Opens the
   // file browser and updates target field when file is selected.
   //
   // @param {VED.event}
   //            evt The event object.
   function browseServer( evt ) {
      var dialog = this.getDialog();
      var editor = dialog.getParentEditor();

      editor._.filebrowserSe = this;

      openFileSelectPopup(
         this.filebrowser.dialog,
         // VED.tools.callFunction.apply( editor._.filebrowserFn )
         function( value ) {
            if( value.src ) {
               updateTargetElement( value.src, editor._.filebrowserSe );
            }
         }
      );
/*
      var width = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowWidth' ] || editor.config.filebrowserWindowWidth || '80%';
      var height = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowHeight' ] || editor.config.filebrowserWindowHeight || '70%';

      var params = this.filebrowser.params || {};
      params.CKEditor = editor.name;
      params.CKEditorFuncNum = editor._.filebrowserFn;
      if ( !params.langCode )
         params.langCode = editor.langCode;

      var url = addQueryString( this.filebrowser.url, params );
      // TODO: V4: Remove backward compatibility (#8163).
      editor.popup( url, width, height, editor.config.filebrowserWindowFeatures || editor.config.fileBrowserWindowFeatures );
*/
   }

   // The onlick function assigned to the 'Upload' button. Makes the final
   // decision whether form is really submitted and updates target field when
   // file is uploaded.
   //
   // @param {VED.event}
   //            evt The event object.
   function uploadFile( evt ) {
      var dialog = this.getDialog();
      var editor = dialog.getParentEditor();

      editor._.filebrowserSe = this;

      // If user didn't select the file, stop the upload.
      if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getInputElement().$.value )
         return false;

      if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getAction() )
         return false;

      return true;
   }

   // Setups the file element.
   //
   // @param {VED.ui.dialog.file}
   //            fileInput The file element used during file upload.
   // @param {Object}
   //            filebrowser Object containing filebrowser settings assigned to
   //            the fileButton associated with this file element.
   function setupFileElement( editor, fileInput, filebrowser ) {
      var params = filebrowser.params || {};
      params.CKEditor = editor.name;
      params.CKEditorFuncNum = editor._.filebrowserFn;
      if ( !params.langCode )
         params.langCode = editor.langCode;

      fileInput.action = addQueryString( filebrowser.url, params );
      fileInput.filebrowser = filebrowser;
   }

   // Traverse through the content definition and attach filebrowser to
   // elements with 'filebrowser' attribute.
   //
   // @param String
   //            dialogName Dialog name.
   // @param {VED.dialog.definitionObject}
   //            definition Dialog definition.
   // @param {Array}
   //            elements Array of {@link VED.dialog.definition.content}
   //            objects.
   function attachFileBrowser( editor, dialogName, definition, elements ) {
      if ( !elements || !elements.length )
         return;

      var element, fileInput;

      for ( var i = elements.length; i--; ) {
         element = elements[ i ];

         if ( element.type == 'hbox' || element.type == 'vbox' || element.type == 'fieldset' )
            attachFileBrowser( editor, dialogName, definition, element.children );

         if ( !element.filebrowser )
            continue;

         if ( typeof element.filebrowser == 'string' ) {
            var fb = {
               action: ( element.type == 'fileButton' ) ? 'QuickUpload' : 'Browse',
               dialog: ucFirst( dialogName ),
               target: element.filebrowser
            };
            element.filebrowser = fb;
         }

         if ( element.filebrowser.action == 'Browse' ) {
            var url = element.filebrowser.url;
            if ( url === undefined ) {
               url = editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'BrowseUrl' ];
               if ( url === undefined )
                  url = editor.config.filebrowserBrowseUrl;
            }

            if ( url ) {
               element.onClick = browseServer;
               element.filebrowser.url = url;
               element.hidden = false;
            } else {
               element.onClick = browseServer;
            }
         } else if ( element.filebrowser.action == 'QuickUpload' && element[ 'for' ] ) {
            url = element.filebrowser.url;
            if ( url === undefined ) {
               url = editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'UploadUrl' ];
               if ( url === undefined )
                  url = editor.config.filebrowserUploadUrl;
            }

            if ( url ) {
               var onClick = element.onClick;
               element.onClick = function( evt ) {
                  // "element" here means the definition object, so we need to find the correct
                  // button to scope the event call
                  var sender = evt.sender;
                  if ( onClick && onClick.call( sender, evt ) === false )
                     return false;

                  return uploadFile.call( sender, evt );
               };

               element.filebrowser.url = url;
               element.hidden = false;
               setupFileElement( editor, definition.getContents( element[ 'for' ][ 0 ] ).get( element[ 'for' ][ 1 ] ), element.filebrowser );
            }
         }
      }
   }

   // Updates the target element with the url of uploaded/selected file.
   //
   // @param {String}
   //            url The url of a file.
   function updateTargetElement( url, sourceElement ) {
      var dialog = sourceElement.getDialog();
      var targetElement = sourceElement.filebrowser.target || null;

      // If there is a reference to targetElement, update it.
      if ( targetElement ) {
         var target = targetElement.split( ':' );
         var element = dialog.getContentElement( target[ 0 ], target[ 1 ] );
         if ( element ) {
            element.setValue( url );
            dialog.selectPage( target[ 0 ] );
         }
      }
   }

   // Returns true if filebrowser is configured in one of the elements.
   //
   // @param {VED.dialog.definitionObject}
   //            definition Dialog definition.
   // @param String
   //            tabId The tab id where element(s) can be found.
   // @param String
   //            elementId The element id (or ids, separated with a semicolon) to check.
   function isConfigured( definition, tabId, elementId ) {
      if ( elementId.indexOf( ";" ) !== -1 ) {
         var ids = elementId.split( ";" );
         for ( var i = 0; i < ids.length; i++ ) {
            if ( isConfigured( definition, tabId, ids[ i ] ) )
               return true;
         }
         return false;
      }

      var elementFileBrowser = definition.getContents( tabId ).get( elementId ).filebrowser;
      return ( elementFileBrowser && elementFileBrowser.url );
   }

   function setUrl( fileUrl, data ) {
      var dialog = this._.filebrowserSe.getDialog(),
         targetInput = this._.filebrowserSe[ 'for' ],
         onSelect = this._.filebrowserSe.filebrowser.onSelect;

      if ( targetInput )
         dialog.getContentElement( targetInput[ 0 ], targetInput[ 1 ] ).reset();

      if ( typeof data == 'function' && data.call( this._.filebrowserSe ) === false )
         return;

      if ( onSelect && onSelect.call( this._.filebrowserSe, fileUrl, data ) === false )
         return;

      // The "data" argument may be used to pass the error message to the editor.
      if ( typeof data == 'string' && data )
         alert( data );

      if ( fileUrl )
         updateTargetElement( fileUrl, this._.filebrowserSe );
   }

   /* --------- */

   /////////////////////////////////////////////////////////////////////////////
   // Function:    jsCallPopupWind
   // Description: Вызывет popup-окно при нажатии кнопок "Создать папку" и "Загрузить файл"
   //
   // In:  action - 'create_folder' or 'upload'
   //
   var jsCallPopupWind = function( action ) {
      popup_texts = {
         create_folder: '<form id="create_folder-form" action=""><div id="field-folder_name" name="popup-folder" class="field"><div>' +
                        '<span class="name">' + inDy.Locale['tab-fs-name'] + '<br>' +
                        '<input type="text" id="folder_name" name="folder_name" value="" class="input" style="width: 375px;">' +
                        '<span class="status" id="name-status">&nbsp;</span></div></div>' +
                        '<div class="cl"></div>' +
                        '<input type="hidden" id="create_folder-caption" value="' + inDy.Locale['tab-fs-create_folder'] + '">' +
                        '<input type="hidden" name="func" value="ajax_files_list_actions">' +
                        '<input type="hidden" id="path_create_folder" name="dir_id" value="">' +
                        '<input type="hidden" name="action" value="create_folder"></form>',

         upload: '<form id="upload-form" name="upload-form" action="" method="post" enctype="multipart/form-data">' +
                 '<div id="field-upload_file" name="popup-upload" class="field"><div>' +
                 '<span class="name">' + inDy.Locale['tab-fs-select'] + '<br>' +
                 '<input type="file" id="upload-file-input" size="48" name="upload_file_name" class="input">' +
                 '<span class="status">&nbsp;</span></div></div>' +
                 '<div class="cl"></div>' +
                 '<input type="hidden" name="func" value="ajax_files_list_actions">' +
                 '<input type="hidden" id="path_upload" name="dir_id" value="">' +
                 '<input type="hidden" name="action" value="upload_file">' +
                 '<input type="hidden" id="upload-caption" value="' + inDy.Locale['tab-fs-upload'] + '">' +
                 '</form>'
      };
      if( !$( action + "-popup-form" ) ) {
         new Element( 'div', {
            id: action + "-popup-form",
            'styles': {
               'position': 'absolute'
            }
         }).injectTop( document.body ).setHTML( popup_texts[action] );

         if( action == 'create_folder' ) {
            inDy._createIndyForm = new inDy.Form( 'create_folder-form', {
               onSubmit: function() {
                  if( $( 'folder_name' ).value == '' ) {
                     inDy._createIndyForm.markFieldAsFalse( 'field-folder_name', inDy.Locale['error-nofill-folder'] );
                     return false;

                  } else if( $( 'folder_name' ).value.search( /^[\w\-_]+$/ ) == -1 ) {
                     inDy._createIndyForm.markFieldAsFalse( 'field-folder_name', inDy.Locale['error-fail-folder'] );
                     return false;
                  } // End if

                  inDy._popupWind.okButton.disable();
                  inDy._popupWind.cancelButton.disable();
                  $( 'path_create_folder' ).value = inDy._objinDyList.dir_id;

                  return true;
               },

               onSuccess: function( result ) {
                  inDy._objinDyList.changeList( result['data'] );

                  inDy._objinDyList.updateTree({
                     add:[{
                        id: inDy._objinDyList.dir_id.replace( /\/$/, '' ) + '/' + $( 'folder_name' ).value,
                        text: $( 'folder_name' ).value
                     }]
                  });

                  $( 'folder_name' ).value = "";
                  Page.Status.showSuccess( inDy.Locale['tab-fs-success-create'], {delay:300} );
                  setTimeout( "inDy._popupWind.hide();", 350 );

                  inDy._popupWind.okButton.enable();
                  inDy._popupWind.cancelButton.enable();
               },

               onFailure: function( result ) {
                  inDy._popupWind.okButton.enable();
                  inDy._popupWind.cancelButton.enable();
                  inDy.Alert( inDy.Locale['error'], result );
               }, // End onFailure

               onError: function( result ) {
                  inDy._popupWind.okButton.enable();
                  inDy._popupWind.cancelButton.enable();

                  if( result.errors ) {
                     inDy.Alert( inDy.Locale['error'], result.errors );
                  } // End if

                  if( result.errorField ) {
                     new Hash( result.errorField ).each( function( el, index  ) {
                        inDy._createIndyForm.markFieldAsFalse( index, el );
                     });

                  } // End if

               } // End onError

            });
         } else {
            inDy._uploadIndyForm = new inDy.Form( 'upload-form', {
               onSubmit: function() {
                  if( $('upload-file-input').value == '' ) {
                     this.markFieldAsFalse( 'field-upload_file', inDy.Locale['error-nofile'] );
                     return false;
                  } // End if

                  this.markFieldAsTrue( 'field-upload_file' );
                  inDy._popupWind.okButton.disable();
                  inDy._popupWind.cancelButton.disable();

                  $( 'path_upload' ).value = inDy._objinDyList.dir_id;
                  return true;

               }, // End onSubmit

               onSuccess: function( result ) {
                  $( 'upload-form' ).reset();

                  // Перестраиваем таблицу файлов
                  inDy._objinDyList.changeList( result['data'] );

                  Page.Status.showSuccess( inDy.Locale['tab-fs-success-upload'], {delay: 300 } );

                  setTimeout( "inDy._popupWind.hide();", 350 );

                  inDy._popupWind.okButton.enable();
                  inDy._popupWind.cancelButton.enable();

               }, // End onSuccess

               onFailure: function( result ) {
                  inDy._popupWind.okButton.enable();
                  inDy._popupWind.cancelButton.enable();
                  inDy.Alert( inDy.Locale['error'], result );
                  return false;

               }, // End onFailure

               onError: function( result ) {
                  inDy._popupWind.okButton.enable();
                  inDy._popupWind.cancelButton.enable();
                  if( result['errors'] ) {
                     inDy.Alert( inDy.Locale['error'], result['errors'].join( '<br>' ) );
                  } else if( result.errorField && result.errorField['field-upload_file'] ) {
                     this.markFieldAsFalse( 'field-upload_file', result.errorField['field-upload_file'] );
                  } // End if
                  return false;

               } // End onError
            });
         } // End if

      } // End if

      inDy._popupWind = new inDy.Popup.Dialog( action + "-popup-form", {
         caption: $( action + "-caption" ).value,
         onPressOk: function() {
            if( action == 'create_folder' ) {
               inDy._createIndyForm.submit();
            } else {
               inDy._uploadIndyForm.submit();
            } // End if

         }, // End onPressOk function

         onPressCancel: function() {
            if( action == 'upload' ) {
               $( 'upload-form' ).reset();
               inDy._uploadIndyForm.markFieldAsTrue( 'field-upload_file' );
            } else {
               $( 'create_folder-form' ).reset();
               inDy._createIndyForm.markFieldAsTrue( 'field-folder_name' );
            } // End if

         }, // End onPressOk function

         onClose: function() {
            if( action == 'upload' ) {
               $( 'upload-form' ).reset();
               inDy._uploadIndyForm.markFieldAsTrue( 'field-upload_file' );
            } else {
               $( 'create_folder-form' ).reset();
               inDy._createIndyForm.markFieldAsTrue( 'field-folder_name' );
            } // End if

         } // End onPressClose function

      });

      inDy._popupWind.show();

      if( action == 'create_folder' ) {
         $( 'folder_name' ).focus();
      } // End if

   } // End function jsCallPopupWind

   ///////////////////////////////////////////////////////////////////////////////
   // Создаем popup-окно для создания папки
   //
   var CCreateFolderPopup = inDy.Popup.Dialog.extend({

      initialize: function( options ) {
         this.parent( 'create_folder-form-popup', options );
      }, // End initialize


      start: function() {
         // Создаем div с содержанием формы
         new Element( 'div', {
            id: "create_folder-form-popup",
            styles: {
               'position': 'absolute'
            }
         }).injectTop( document.body ).setHTML(
            '<form id="create_folder-form" action=""><div id="field-folder_name" name="popup-folder" class="field"><div class="field-inner">' +
            '<span class="name">' + inDy.Locale['tab_fs_name'] + '<br>' +
            '<input type="text" id="folder_name" name="folder_name" value="" class="input" style="width: 375px;">' +
            '<span class="status" id="name-status">&nbsp;</span></div></div>' +
            '<div class="cl"></div>' +
            '<input type="hidden" name="dir_id" value="">' +
            '<input type="hidden" name="action" value="create_folder"></form>'
         );

         this.addElement(
            new CFormElement( 'create_folder-form', {
               onSubmit: function() {
                  if( $( 'folder_name' ).value == '' ) {
                     this.markFieldAsFalse( 'field-folder_name', inDy.Locale['error_nofill_folder'] );
                     return false;

                  } else if( $( 'folder_name' ).value.search( /^[\w\-_.А-Яа-яЁё]+$/ ) == -1 ) {
                     this.markFieldAsFalse( 'field-folder_name', inDy.Locale['error_file_name'] );
                     return false;

                  } else {
                     $( 'create_folder-form' ).getElement( 'input[name=dir_id]' ).value = inDy._filesList.dir_id;
                  } // End if

                  Page.Status.showProgress( 'Создание папки...' );
                  return true;

               }, // End onSubmit

               onError: function() {
                  Page.Status.hide();
               },

               onSuccess: function() {
                  Page.Status.showSuccess( 'Папка создана' );
               } // End onSubmit

            })
         );

         this.parent();

         this.setCaption( inDy.Locale['tab_fs_create_folder'] );

         Page.addEvent( 'create_folder-form-popup-okButton-click', function() { Page.fireEvent( 'create_folder-form-send', 'fs_create_folder' ); } );
         Page.addEvent( 'create_folder-form-success', function() { Page.fireEvent( 'indy-list-reload' ); } );
         Page.addEvent( 'create_folder-form-success', function() { Page.fireEvent( 'create_folder-form-popup-close' ); } );
         Page.addEvent( 'create_folder-form-popup-open', function() {
            $( 'folder_name' ).focus();
         });

      } // End start


   });

   // Добавляем к списку форму
   Page.addElement( new CCreateFolderPopup() );



   ///////////////////////////////////////////////////////////////////////////////
   // Создаем popup-окно для загрузки файла
   //
   var CUploadPopup = inDy.Popup.Dialog.extend({

      initialize: function( options ) {
         this.parent( 'upload-form-popup', options );
      }, // End initialize


      start: function() {
         // Создаем div с содержанием формы
         new Element( 'div', {
            id: "upload-form-popup",
            styles: {
               'position': 'absolute',
               'display': 'block'
            }
         }).injectTop( document.body ).setHTML(
            '<form id="upload-form" name="upload-form" action="" method="post" enctype="multipart/form-data">' +
            '<div id="field-upload_file" name="popup-upload" class="field"><div class="field-inner">' +
            '<span class="name">' + inDy.Locale['tab_fs_select'] + '<br>' +
            '<input type="file" size="48" name="upload_file_name" class="input">' +
            '<span class="status">&nbsp;</span></div></div>' +
            '<div class="cl"></div>' +
            '<input type="hidden" name="dir_id" value="">' +
            '<input type="hidden" name="action" value="upload_file">' +
            '</form>'
         );

         this.addElement(
            new CFormElement( 'upload-form', {
               onSubmit: function() {
                  if( $( 'upload-form' ).getElement( 'input[name=upload_file_name]' ).value == '' ) {
                     this.markFieldAsFalse( 'field-upload_file', inDy.Locale['error_nofile'] );
                     return false;

                  } else {
                     this.markFieldAsTrue( 'field-upload_file' );
                     $( 'upload-form' ).getElement( 'input[name=dir_id]' ).value = inDy._filesList.dir_id;

                     return true;

                  } // End if

                  Page.Status.showProgress( 'Загрузка файла...' );

               }, // End onSubmit

               onSuccess: function() {
                  Page.Status.showSuccess( 'Файл загружен' );
               } // End onSubmit

            })
         );

         this.parent();

         this.setCaption( inDy.Locale['tab_fs_Upload'] );

         Page.addEvent( 'upload-form-popup-okButton-click', function() { Page.fireEvent( 'upload-form-send', 'fs_upload_file' ); } );
         Page.addEvent( 'upload-form-success', function() {
            Page.fireEvent( 'indy-list-reload' );
            Page.fireEvent( 'upload-form-popup-close' );
         });

      } // End start


   });

   Page.addElement( new CUploadPopup() );


   ///////////////////////////////////////////////////////////////////////////////
   // Создаем popup-окно для переименования файла
   //
   var CRenamePopup = inDy.Popup.Dialog.extend({

      initialize: function( options ) {
         this.parent( 'rename-form-popup', options );
      }, // End initialize


      start: function() {
         // Создаем div с содержанием формы
         new Element( 'div', {
            id: "rename-form-popup",
            'styles': {
               'position': 'absolute'
            }
         }).injectTop( document.body ).setHTML(
            '<form id="rename-form" name="rename-form" action="" method="post">' +
            '<div id="field-file_name" name="popup-upload" class="field"><div class="field-inner">' +
            '<span class="name">' + inDy.Locale['tab_fs_new_name'] + '<br>' +
            '<input type="text" style="width: 375px;" name="new_name" class="input">' +
            '<span class="status">&nbsp;</span></div></div>' +
            '<div class="cl"></div>' +
            '<input type="hidden" name="dir_id" value="">' +
            '<input type="hidden" name="action" value="rename">' +
            '<input type="hidden" name="file_id" value="">' +
            '</form>'
         );

         this.addElement(
            new CFormElement( 'rename-form', {
               onSubmit: function() {
                  var file_name = $( 'rename-form' ).getElement( 'input[name=new_name]' ).value;

                  if( file_name == '' ) {
                     this.markFieldAsFalse( 'field-file_name', inDy.Locale['error_nofile'] );
                     return false;
                  } else if( file_name.search( /^[\w\-_.А-Яа-яЁё]+$/ ) == -1 ) {
                     this.markFieldAsFalse( 'field-file_name', inDy.Locale['error_file_name'] );
                     return false;
                  } // End if

                  this.markFieldAsTrue( 'field-file_name' );

                  $( 'rename-form' ).getElement( 'input[name=dir_id]' ).value = inDy._filesList.dir_id;

                  Page.Status.showProgress( 'Переименование файла...' );

                  return true;

               }, // End onSubmit

               onError: function() {
                  Page.Status.hide();
               },

               onSuccess: function() {
                  Page.Status.showSuccess( 'Файл переименован' );
               } // End onSubmit

            })
         );

         this.parent();

         this.setCaption( inDy.Locale['tab_fs_Rename'] );

         Page.addEvent( 'rename-form-popup-okButton-click', function() { Page.fireEvent( 'rename-form-send', 'fs_rename' ); } );
         Page.addEvent( 'rename-form-success', function() { Page.fireEvent( 'indy-list-reload' ); } );
         Page.addEvent( 'rename-form-success', function() { Page.fireEvent( 'rename-form-popup-close' ); } );
         Page.addEvent( 'rename-form-popup-open', function() {
            var file_id = inDy._filesList.getSelected()[0];
            $( 'rename-form' ).getElement( 'input[name=file_id]' ).value = file_id;

            var el = $( 'rename-form' ).getElement( 'input[name=new_name]' );
            el.value = file_id.replace( /^\/([^\/]+\/)*/, '' );
            el.select();

         });

      } // End start


   });

   Page.addElement( new CRenamePopup() );



   ///////////////////////////////////////////////////////////////////////////////
   // Открывает окно выбора файла
   //
   function openFileSelectPopup( mode, setParams ) {
      if( mode == 'Image' ) {
         div_id = 'select-img-div';
      } else {
         div_id = 'select-file-div';
      } // End if

      // Создаем контентый DIV
      if( !$( div_id ) ) {
         new Element( 'div', {
            id: div_id,
            styles: {
               width: window.getWidth() - 100,
               height: window.getHeight() - 200,
               'overflow-y': 'scroll',
               position: 'absolute'
            }
         }).injectTop( document.body ).setHTML('<div id="indy-list"></div>');

         Popup = new inDy.Popup.Dialog( div_id, {
            caption: mode == 'Image' ? 'Выбор изображения' : 'Выбор файла'
         });

         Page.addElement( Popup );

         Page.sendAction( 'fs_get_rubrics', '', function( result ) {

            // Создаем список
            inDy._filesList = new CListElementDelBtn( 'indy-list', {
               caption: inDy.Locale['tab_fs'],
               empty: inDy.Locale['tab_fs_empty'],
               copyPaste: true,
               getListAction: 'fs_get_list',
               deleteAction: 'fs_delete',
               addQueryString: mode == 'Image' ? 'only_img=1' : '',

               sort: {
                  type: 'value',
                  by: 'name'
               }, // sort
               columns: [{
                  fieldType: 'string',
                  fieldName: 'name',
                  caption: inDy.Locale['tab_fs_name'],
                  drag: true,
                  sort: true
               },{
                  fieldType: 'int',
                  fieldName: 'size',
                  caption: inDy.Locale['size'],
                  className: 'size-column',
                  width: '120',
                  sort: true
               },{
                  fieldType: 'date',
                  fieldName: 'time',
                  caption: inDy.Locale['tab_fs_time'],
                  className: 'date-time',
                  width: '170',
                  sort: true
               }],

               buttons:[{
                  id: 'upload',
                  caption: inDy.Locale['tab_fs_upload'],
                  type: 'btn-add',
                  onClick: Page.fireEvent.bind( Page, ['upload-form-popup-open'] )
               },{
                  id: 'create_folder',
                  caption: inDy.Locale['tab_fs_create_folder'],
                  type: 'btn-add',
                  onClick: Page.fireEvent.bind( Page, ['create_folder-form-popup-open'] )
               },{
                  id: 'rename',
                  locked: true,
                  caption: inDy.Locale['tab_fs_rename'],
                  onClick: Page.fireEvent.bind( Page, ['rename-form-popup-open'] )
               }],

               prepareFunc: function( tbl_data ) {
                  for( var number = 0; number < tbl_data.length; number++ ) {

                     if( !tbl_data[number]['isDir'] ) {
                        // если это изображение
                        if( /\.(jpg|png|gif|bmp)$/i.test( tbl_data[number]['id'] ) ) {
                           tbl_data[number]['name'].slimbox = {
                              caption: tbl_data[number]['name']['value'],
                              href: inDy.Config.fsRoot + tbl_data[number]['id']
                           };

                        } // End if

                        tbl_data[number]['className'] = 'isFile';

                     } // End if

                     if( !tbl_data[number]['isDir'] ) {
                        tbl_data[number]['name']._onClick = function( level, data ) {
                           if( mode == 'Image' ) {
                              setParams({
                                 'src': inDy.Config.fsRoot + data['id'],
                                 'width': data['width'],
                                 'height': data['height']
                              });
                           } else {
                              setParams({
                                 'src': inDy.Config.fsRoot + data['id']
                              });
                           } // End if

                           // Закрываем окно выбора файлов
                           Page.fireEvent( div_id + '-close' );

                        } // End _onClick

                     } // End if

                     if( !tbl_data[number]['isDir'] ) {
                        // если это изображение
                        if( /\.(jpg|png|gif|bmp)$/.test( tbl_data[number]['id'] ) ) {
                           tbl_data[number]['name'].slimbox = {
                              caption: tbl_data[number]['name']['value'],
                              href: inDy.Config.fsRoot + tbl_data[number]['id']
                           };

                        } // End if

                        tbl_data[number]['className'] = 'isFile';

                     } // End if

                     if( tbl_data[number]['size'] && typeof( tbl_data[number]['size']['valueForSort'] ) != 'undefined' ) {
                        if( tbl_data[number]['size']['valueForSort'] < 1024 ) {
                           tbl_data[number]['size']['value'] = '<span class="less">менее</span>1 ' + inDy.Locale['size_1'];
                        } else {
                           tbl_data[number]['size']['value'] = Math.ceil( tbl_data[number]['size']['valueForSort'] / 1024 ) + " " + inDy.Locale['size_1'];
                        } // End if

                     } // End if

                  } // End for

               }, // prepareFunc

               header: {},

               tree: {
                  data: result
               },

               dragOptions: {
                  // Реакция на бросание элемента
                  onDrop: function( list, to, from, names ) {
                     // Прогресс-бар
                     Page.Status.showProgress( 'Сохранение...' );

                     // Посылаем запрос
                     Page.sendAction( 'fs_drag_remove', 'dir_id=' + list.dir_id + '&names[]=' + names + '&to=' + to + '&from=' + from + list.getNodesString(), function( result ){
                        // Обновляем список
                        Page.fireEvent( 'indy-list-reload' );

                        // Показываем подтверждающий статус
                        Page.Status.showSuccess( 'Изменения сохранены' );

                     });


                  }, // onDrop

                  // Список элементов доступных для бросания текущего элемента
                  dropToList : function( dragItem ) {
                     var result = new Array();

                     if( dragItem ) {
                        $$( '.indy-list-item' ).each( function( item ) {
                           if( item.getProperty( 'name' ) != dragItem.getProperty('name') && !item.hasClass( 'isFile' ) ) {
                              result.push( item );
                           } // End if

                        });  // End .each

                     } // End if

                     return result;

                  }, // dropToList

                  // Инициализация перед началом движения
                  onDragStart: function( pageList ) {
                     // Помечаем те, которые тащим
                     $$( '.indy-list-item' ).each( function( item ) {
                        if( item.getProperty( 'name' ) == pageList.dragItem.getProperty('name') ) {
                           item.addClass('dragging');
                        } // End if

                     }); // End .each

                     // Подсвечиваем элемент, на который тащим
                     pageList.options.dragOptions.dropToList( pageList.dragItem ).each( function( item ) {
                        item.addEvents({
                           'mouseover': function( e ) {
                              this.addClass( 'insert-inside' );
                           }, // mousemove

                           'mouseout': function( e ) {
                              this.removeClass( 'insert-inside' );
                           } // mouseout

                        }); // End addEvents

                     }); // End .each

                  }, // onDragStart

                  // Завершениие перетаскивания
                  onDragComplete: function( pageList ) {
                     pageList.options.dragOptions.dropToList( pageList.dragItem ).each( function( item ) {
                        item.removeEvents( 'mouseover' );
                        item.removeEvents( 'mouseout' );

                     }); // End .each

                     $$( '.indy-list-item' ).each( function( item ) {
                        if( item.hasClass( 'dragging' ) ) {
                           item.removeClass('dragging');
                        } // End if

                     }); // End .each

                  } // onDragComplete

               } // dragOptions

            });

            // Добавляем список на страницу
            Page.addElement( inDy._filesList );

            // Подвешиваем событие на выбор/снятие выбора с элемента списка
            Page.addEvent( 'indy-list-select', ( function() {
               if( this.getSelected().length == 1 ) {
                  this.getButton( 'rename' ).enable();
               } else {
                  this.getButton( 'rename' ).disable();
               } // End if

            }).bind( inDy._filesList ) );



         });

      } // End if


      // Открывем окно
      Page.fireEvent( div_id + '-open' );

   }; // End openFileSelectPopup

   /* --------- */

   VED.plugins.add( 'filebrowser', {
      requires: 'popup',
      init: function( editor, pluginPath ) {
         editor._.filebrowserFn = VED.tools.addFunction( setUrl, editor );
         editor.on( 'destroy', function() {
            VED.tools.removeFunction( this._.filebrowserFn );
         });
      }
   });

   VED.on( 'dialogDefinition', function( evt ) {
      var definition = evt.data.definition,
         element;
      // Associate filebrowser to elements with 'filebrowser' attribute.
      for ( var i = 0; i < definition.contents.length; ++i ) {
         if ( ( element = definition.contents[ i ] ) ) {
            attachFileBrowser( evt.editor, evt.data.name, definition, element.elements );
            if ( element.hidden && element.filebrowser ) {
               element.hidden = !isConfigured( definition, element[ 'id' ], element.filebrowser );
            }
         }
      }
   });


})();

/**
 * The location of an external file browser that should be launched when the **Browse Server**
 * button is pressed. If configured, the **Browse Server** button will appear in the
 * **Link**, **Image**, and **Flash** dialog windows.
 *
 * See the [File Browser/Uploader](http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_(Uploader\)) documentation.
 *
 *      config.filebrowserBrowseUrl = '/browser/browse.php';
 *
 * @since 3.0
 * @cfg {String} [filebrowserBrowseUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The location of the script that handles file uploads.
 * If set, the **Upload** tab will appear in the **Link**, **Image**,
 * and **Flash** dialog windows.
 *
 * See the [File Browser/Uploader](http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_(Uploader\)) documentation.
 *
 *      config.filebrowserUploadUrl = '/uploader/upload.php';
 *
 * @since 3.0
 * @cfg {String} [filebrowserUploadUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The location of an external file browser that should be launched when the **Browse Server**
 * button is pressed in the **Image** dialog window.
 *
 * If not set, CKEditor will use {@link VED.config#filebrowserBrowseUrl}.
 *
 *      config.filebrowserImageBrowseUrl = '/browser/browse.php?type=Images';
 *
 * @since 3.0
 * @cfg {String} [filebrowserImageBrowseUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The location of an external file browser that should be launched when the **Browse Server**
 * button is pressed in the **Flash** dialog window.
 *
 * If not set, CKEditor will use {@link VED.config#filebrowserBrowseUrl}.
 *
 *      config.filebrowserFlashBrowseUrl = '/browser/browse.php?type=Flash';
 *
 * @since 3.0
 * @cfg {String} [filebrowserFlashBrowseUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The location of the script that handles file uploads in the **Image** dialog window.
 *
 * If not set, CKEditor will use {@link VED.config#filebrowserUploadUrl}.
 *
 *      config.filebrowserImageUploadUrl = '/uploader/upload.php?type=Images';
 *
 * @since 3.0
 * @cfg {String} [filebrowserImageUploadUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The location of the script that handles file uploads in the **Flash** dialog window.
 *
 * If not set, CKEditor will use {@link VED.config#filebrowserUploadUrl}.
 *
 *      config.filebrowserFlashUploadUrl = '/uploader/upload.php?type=Flash';
 *
 * @since 3.0
 * @cfg {String} filebrowserFlashUploadUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The location of an external file browser that should be launched when the **Browse Server**
 * button is pressed in the **Link** tab of the **Image** dialog window.
 *
 * If not set, CKEditor will use {@link VED.config#filebrowserBrowseUrl}.
 *
 *      config.filebrowserImageBrowseLinkUrl = '/browser/browse.php';
 *
 * @since 3.2
 * @cfg {String} [filebrowserImageBrowseLinkUrl='' (empty string = disabled)]
 * @member VED.config
 */

/**
 * The features to use in the file browser popup window.
 *
 *      config.filebrowserWindowFeatures = 'resizable=yes,scrollbars=no';
 *
 * @since 3.4.1
 * @cfg {String} [filebrowserWindowFeatures='location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes']
 * @member VED.config
 */

/**
 * The width of the file browser popup window. It can be a number denoting a value in
 * pixels or a percent string.
 *
 *      config.filebrowserWindowWidth = 750;
 *
 *      config.filebrowserWindowWidth = '50%';
 *
 * @cfg {Number/String} [filebrowserWindowWidth='80%']
 * @member VED.config
 */

/**
 * The height of the file browser popup window. It can be a number denoting a value in
 * pixels or a percent string.
 *
 *      config.filebrowserWindowHeight = 580;
 *
 *      config.filebrowserWindowHeight = '50%';
 *
 * @cfg {Number/String} [filebrowserWindowHeight='70%']
 * @member VED.config
 */





